package com.appspot.abcensys.server.DAO.JDO;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;

import com.appspot.abcensys.server.CalendarSupplier;
import com.appspot.abcensys.server.PMF;
import com.appspot.abcensys.server.DAO.LesDAO;
import com.appspot.abcensys.shared.Gebruiker;
import com.appspot.abcensys.shared.Les;

public class LesDAO_JDO implements LesDAO {

	private CalendarSupplier cal = new CalendarSupplier();

	private static final Logger log = Logger.getLogger(LesDAO_JDO.class.getName());

	/**
	 * Haalt alle lessen op a.d.v een where conditie.
	 * 
	 * @param String
	 *            met where conditie
	 * @return ArrayList<Les> met alle gehaalde lessen.
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Les> getLes(String where) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " " + where;
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		lessen.size();
		pm.close();

		for (Les l : lessen) {
			l.fix();
		}

		log.info("getLes(" + where + ") | Lessen: " + lessen);

		return lessen;
	}

	/**
	 * @param Les
	 *            bevat een Les object
	 * @return Boolean geeft terug of het opslaan van het object is gelukt
	 */
	public boolean addLes(Les l) {
		boolean b = false;
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			pm.makePersistent(l);
			b = true;
		} finally {
			pm.close();
		}

		log.info("addLes(" + l.toString() + ") | Is gelukt " + b);

		return b;
	}

	/**
	 * @param klascode
	 *            klascode waar op gezocht word
	 * @param weeknummer
	 *            weeknummer waar op gezocht word
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Les> getLesByKlasAndWeeknummer(String klascode, int weeknummer) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " WHERE klasCode == \"" + klascode + "\" && weekNummer == " + weeknummer + " && jaar == " + cal.getJaar() + " ORDER BY lesDatum ASC";
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		lessen.size();
		pm.close();

		log.info("getLesByKlasAndWeeknummer(" + klascode + ", " + weeknummer + ") | Lessen: " + lessen);

		return lessen;
	}

	/**
	 * Haalt het lesrooster op voor een klas a.d.v. de datum van vandaag en
	 * morgen.
	 * 
	 * @param String
	 *            klascode
	 * @param String
	 *            datumVandaag
	 * @param String
	 *            datumMorgen
	 * @return List<Les> lesobjecten en anders null
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Les> getLesByKlasAndDatumVandaagEnMorgen(String klascode, String datumVandaag, String datumMorgen) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " WHERE klasCode == \"" + klascode + "\" && (lesDatum == \"" + datumVandaag + "\" || lesDatum == \"" + datumMorgen
				+ "\") ORDER BY lesDatum ASC";
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		lessen.size();
		pm.close();

		log.info("getLesByKlasAndDatumVandaagEnMorgen(" + klascode + ", " + datumVandaag + ", " + datumMorgen + ") | Lessen: " + lessen);

		return lessen;
	}

	/**
	 * Haalt alle lessen op van de verstuurde Gebruiker/Docent
	 * 
	 * @param Gebruiker
	 *            gebruiker waarvan de lessen worden opgehaald
	 * @return ArrayList<Les> met de opgehaalde lessen, anders null
	 */
	public ArrayList<Les> getLesByDocent(Gebruiker g) {
		String docentNaam = g.getVoornaam() + " " + g.getAchternaam();
		ArrayList<Les> lessen = this.getLes("");
		ArrayList<Les> docentLessen = new ArrayList<Les>();
		for (Les les : lessen) {
			for (String docent : les.getDocenten()) {
				if (docentNaam.equals(docent)) {
					docentLessen.add(les);
				}
			}
		}

		log.info("getLesByDocent(" + g.toString() + ") | Lessen: " + lessen);

		return docentLessen;
	}

	/**
	 * Haalt een Les op a.d.v zijn Id
	 * 
	 * @param Long
	 *            van de op te halen Les
	 * @return Les die is opgehaald, anders null
	 */
	@SuppressWarnings("unchecked")
	public Les getLesById(Long id) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " WHERE id == " + id;
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		lessen.size();
		pm.close();

		Les les = null;
		if (lessen != null && !lessen.isEmpty()) {
			les = lessen.get(0);
		}

		log.info("getLesById(" + id + ") | Lessen: " + lessen + " & Les: " + les.toString());

		return les;
	}

	/**
	 * Haalt alle Les objecten op
	 * 
	 * @return ArrayList<Les> met alle Les objecten
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Les> getLessenOrderByVakcode() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " ORDER BY vakCode ASC";
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		lessen.size();
		pm.close();

		log.info("getLessen() | Lessen: " + lessen);

		return lessen;
	}

	/**
	 * Haalt alle VakCodes op van het Rooster
	 * 
	 * @return ArrayList<String> met alle VakCodes
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<String> getVakCodes() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " ORDER BY vakCode ASC";
		ArrayList<Les> result = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		result.size();
		pm.close();

		ArrayList<String> vakCodes = new ArrayList<String>();

		for (Les les : result) {
			if (!vakCodes.contains(les.getVakCode())) {
				vakCodes.add(les.getVakCode());
			}
		}

		log.info("getVakCodes() | vakCodes: " + vakCodes);

		return vakCodes;
	}

	/**
	 * Haalt alle Les objecten op die overeenkomen met de meegegeven vakCode
	 * 
	 * @param String
	 *            met vakCode
	 * @return ArrayList<Les> met alle opgehaalde Les objecten
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Les> getLesByVakCode(String vakCode) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " WHERE vakCode == \"" + vakCode + "\"";
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		lessen.size();
		pm.close();

		log.info("getLesByVakCode(" + vakCode + ") | Lessen: " + lessen);

		return lessen;
	}

	/**
	 * Haalt alle Vakcodes op a.d.v een klascode
	 * 
	 * @param String
	 *            klascode waar op gezocht word
	 * @return ArrayList<String> met vakcodes
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<String> getGebruikerVakCodesByKlasCode(String klascode) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " WHERE klasCode == \"" + klascode + "\"";
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		lessen.size();
		pm.close();

		ArrayList<String> vakcodes = new ArrayList<String>();
		for (Les les : lessen) {
			vakcodes.add(les.getVakCode());
		}

		log.info("getGebruikerVakCodesByKlasCode(" + klascode + ") | Vakcodes: " + vakcodes);

		return vakcodes;
	}

	/**
	 * Haalt het aantal lessen op die zijn geweest/komen
	 * 
	 * @see com.appspot.abcensys.server.DAO.JDO.LesDAO_JDO#getTotaalAantalLessenByKlasAndVakcode(String,
	 *      String)
	 * @param String
	 *            met klascode
	 * @param String
	 *            met vakcode
	 * @return int met het aantal lessen die zijn geweest
	 */
	@SuppressWarnings("unchecked")
	public int getTotaalAantalLessenByKlasAndVakcode(String klascode, String vakcode) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " WHERE klasCode == \"" + klascode + "\" && vakCode == \"" + vakcode + "\"";
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		int a = lessen.size();
		pm.close();

		log.info("getTotaalAantalLessenByKlasAndVakcode(" + klascode + ", " + vakcode + ") | Aantal: " + a);

		return a;
	}

	/**
	 * Haalt Les objecten op a.d.v een Faculteit code
	 * 
	 * @param String
	 *            van de faculteit
	 * @return ArrayList<Les> met Les objecten
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Les> getLesByFaculteit(String faculteit) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Les.class.getName() + " WHERE fackulteit == \"" + faculteit + "\"";
		ArrayList<Les> lessen = new ArrayList<Les>(pm.detachCopyAll((List<Les>) pm.newQuery(query).execute()));

		lessen.size();
		pm.close();

		log.info("getLesByFaculteit(" + faculteit + ") | Lessen: " + lessen);

		return lessen;
	}
}
